#ifndef __PROTONET_HPP__
#define __PROTONET_HPP__

#include <string>
#include "../../netlib/netlib/netlib.h"

/**
*@file       protonet.hpp
*@brief      protobuf network helper
*
*@author     graywind
*@version    1.0.0.0
*@data       2012/02/13
*/

template<typename proto_type>
class ProtoNet
{
public:
	///@brief   create a protobuf from bytes
	///param[in] pMsgBuffer    message buffer
	///param[in] msg_bytes     byte length of message buffer
	///retval    bool
	static bool CreateFromBytes(proto_type& p, void* pMsgBuffer, unsigned long msg_bytes)
	{
		return p.ParseFromArray(pMsgBuffer, msg_bytes);
	}
	///@brief   broadcast a message to all live sessions
    ///param[in]  msg_id      message identification
	///param[in]  p           any protobuf types
    ///param[in]  usage_type  type of usage how the session has been used
	///retval   void
	static void Broadcast(unsigned long msg_id, proto_type& p, eUsageType usage_type)
	{
		std::string buff = IntoBytes(p);
		broadcast_msg(msg_id, buff.length(), (void*)buff.c_str(), usage_type);
	}
	///@brief   send a message
    ///param[in]  session_index   index of the session in the array
    ///param[in]  msg_id          message identification
	///param[in]  p               any protobuf types
	///retval   void
	static void Send(int session_id, unsigned long msg_id, proto_type& p)
	{
		std::string buff = IntoBytes(p);
        send_msg(session_id, msg_id, buff.length(), (void*)buff.c_str());
	}

	///@brief   convert into bytes
	///param[in] p                any protobuf types
	///retval   std::string       
	static std::string IntoBytes(proto_type& p)
	{
		return p.SerializeAsString();
	}
};

template<>
class ProtoNet<void>
{
public:
    ///@brief   broadcast a message to all live sessions
    ///param[in]  msg_id      message identification
    ///param[in]  usage_type  type of usage how the session has been used
	///retval   void
    static void Broadcast(unsigned long msg_id, eUsageType usage_type)
    {
        broadcast_msg(msg_id, 0, 0, usage_type);
    }
    ///@brief   send a message
    ///param[in]  session_index   index of the session in the array
    ///param[in]  msg_id          message identification
	///retval   void
	static void Send(int session_id, unsigned long msg_id)
	{
        send_msg(session_id, msg_id, 0, 0);
	}
};

#endif